package com.pureland.storage;

import com.pureland.storage.bean.Storage;
import com.pureland.storage.bean.StorageResult;
import io.minio.MinioClient;
import io.minio.errors.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @projectName: pureland_cloud
 * @className: com.pureland.storage.StorageTemplate
 * @description: 存储模块顶层抽象接口
 * @author: tong.li
 * @createTime: 2020/10/19 14:28
 * @version: v1.0
 * @copyright: 版权所有 李彤 © 2020
 */
public interface StorageTemplate {

    /**
     * bean 初始方法
     */
    void init();



    /**
     *  远程文件上传
     *
     * @param storage       storage
     * @param url           上传的文件
     * @param contentType    contentType
     * @return 上传结果
     */
    StorageResult upload(Storage storage, String url, String contentType);

    /**
     * 本地File文件上传
     *
     * @param storage storage
     * @param file    上传的文件
     * @param contentType    contentType
     * @return 上传结果
     */
    StorageResult upload(Storage storage, File file, String contentType);


    /**
     * 流上传
     * @param storage
     * @param inputStream
     * @param contentType    未知可填null
     * @param contentLength  未知的话请填写FileUtils.DEFAULT_CONTENT_LENGTH_UNKOWN
     * @return
     */
    StorageResult upload(Storage storage,  InputStream inputStream, String contentType,  long contentLength);

    /**
     * 字节数组文件上传
     *
     * @param storage storage
     * @param bytes   上传的文件字节数组
     * @return 上传结果
     */
    StorageResult upload(Storage storage, byte[] bytes);



    String DATE_FORMART_MONTH  = "yyyyMM";

    String DATE_FORMART_DAY  = "yyyyMMdd";


    /**
     * 路径前缀规则
     *
     * @param rule 规则
     * @param prefix prefix
     * @return 前缀
     */
    default String getPrefix(Storage.PrefixRule rule, String prefix) {
        if (rule == null) {
            return prefix;
        }
        LocalDateTime now = LocalDateTime.now();
        switch (rule) {
            case NOW_DATE_MOUTH:
                return  DateTimeFormatter.ofPattern(DATE_FORMART_MONTH).format(now);
            case NOW_DATE_MOUTH_DAY:
                return DateTimeFormatter.ofPattern(DATE_FORMART_DAY).format(now);
            case NONE:
            default:
                return prefix;
        }
    }

    /**
     * 检查bucket,若不存在则创建该bucket
     * @param minioClient
     * @param bucketName
     * @throws IOException
     * @throws InvalidKeyException
     * @throws InvalidResponseException
     * @throws RegionConflictException
     * @throws InsufficientDataException
     * @throws NoSuchAlgorithmException
     * @throws ServerException
     * @throws InternalException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws ErrorResponseException
     */
    void checkBucketAndCreate(MinioClient minioClient, String bucketName) throws IOException, InvalidKeyException, InvalidResponseException, RegionConflictException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException;

    /**
     * 根据bucketName和对象名获取文件流
     * @param bucketName
     * @param objectName
     * @return
     */
    InputStream getObjectStream(String bucketName, String objectName);

    /**
     * 根据bucketName和对象名获取公共访问的文件地址
     * @param bucketName
     * @param objectName
     * @return
     */
    String getPublicObjectUrl(String bucketName, String objectName);

    /**
     * 根据bucketName和对象名获取预签名(有效期)的文件地址
     * @param bucketName
     * @param objectName
     * @return
     */
    String getPresignedObjectUrl(String bucketName, String objectName);
}
